#include <cassert>

#include "basicmembershipfunction.h"

BasicMembershipFunction::BasicMembershipFunction(const QString &type,
                                                 const int &size):
        m_type(type),
        m_name(""),
        m_size(size),
        m_points(new QPointF[m_size]),
        m_crisp_value(0),
        m_fuzzy_value(0),
        m_is_output(false)
{
}

BasicMembershipFunction::BasicMembershipFunction(const BasicMembershipFunction &src):
        m_points(0)
{
    /* I don't really know what the spacing rules are for lines like the one
     * above.  Changing it would look really bad, but it's over the recomended
     * length... :S
     */
    *this = src;
}

BasicMembershipFunction::~BasicMembershipFunction()
{
    delete[] m_points;
}

void BasicMembershipFunction::operator = (const BasicMembershipFunction& src)
{
    m_size = src.m_size;

    delete[] m_points;

    m_points = new QPointF[m_size];

    for( int i = 0; i < m_size; ++i )
        m_points[i] = src.m_points[i];

    m_crisp_value = src.m_crisp_value;
    m_fuzzy_value = src.m_fuzzy_value;
}

void BasicMembershipFunction::setPoint(const int& point,
                                       const double& newLocation)
{
    assert(point >= 0 && point < m_size);

    m_points[point].setX(newLocation);
}

double BasicMembershipFunction::getPoint(const int& point) const
{
    assert(point >= 0 && point < m_size);

    return m_points[point].x();
}

void BasicMembershipFunction::shiftShape(const double& amount)
{
    for (int i = 0; i < m_size; ++i)
    {
        m_points[i].setX(m_points[i].x() + amount);
    }
}

double BasicMembershipFunction::getCrispValue()
{
    calculateCentroid();
    return m_crisp_value;
}

void BasicMembershipFunction::setFuzzyValue(const double& probabilityLevel)
{
    /* Set up the probability level. Needed in the output functions.
     * Must be between 0 and 1 since probability is between 0 and 1.
     */
    assert(probabilityLevel >= 0 && probabilityLevel <= 1);

    m_fuzzy_value = probabilityLevel;
}

QDebug operator<<(QDebug dbg, const BasicMembershipFunction &funct) {

    dbg.nospace() << "Membership function of size " << funct.getSize();
    dbg.nospace() << "\nPoints:";
    for(int i = 0; i < funct.getSize(); ++i)
        dbg.nospace() << "\n\t" << funct.getPoints()[i];

    return dbg.space();
}
